package com.kitty.game.activity.service.other;

import com.kitty.common.utils.SpringUtils;
import com.kitty.common.core.SchedulerManager;
import com.kitty.game.activity.model.product.ActivityType;
import com.kitty.game.activity.service.time.FightActivityHandler;
import com.kitty.game.boss.config.BossSet;
import com.kitty.game.boss.model.BossFightParam;
import com.kitty.game.boss.model.BossParam;
import com.kitty.game.boss.service.NewBossService;
import com.kitty.game.chat.service.ChatService;
import com.kitty.game.config.NPC;
import com.kitty.game.enter.Position;
import com.kitty.game.fight.bean.Fight;
import com.kitty.game.fight.service.FightService;
import com.kitty.game.npc.model.NpcButton;
import com.kitty.game.role.model.Role;
import com.kitty.game.team.model.Team;
import com.kitty.game.utils.Const;
import com.kitty.game.utils.TimeUtil;
import com.kitty.listener.event.FightEndEvent;
import com.kitty.mina.cache.DataCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

/*异族入侵处理类*/
@Component
public class AlienIntrusionDandler extends FightActivityHandler {

    /**
     * 无名小镇和东海渔村
     */
    private static final List<Integer> MAPIDS = Arrays.asList(23000);
    @Autowired
    ChatService chatService;
    @Autowired
    FightService fightService;
    /**
     * 每个地图显示的地府叛军数量
     */
    private static final int PIRATE_COUNT_PER_MAP = 20;
    private static final String PIRATE_NAME = "异族小将";
    private static final int PIRATE_ICON = 20056;
    private static final int ACCEPT_MIN_LEVEL = 60;
    /**
     *异族入侵持续时间，单位毫秒    15分钟
     */
    //private static final long PIRATE_CONTINUED_TIME = 15 * TimeUtil.ONE_MINUTE;

    /**
     * 最少组队人数
     */
    private static final int MIN_TEAM_COUNT = 1;
    private static final String KILL_MESSAGE = "刚刚有#R1#n名#Y异族#n被我们的英雄消灭了！真是了不起啊！尚有#R{0}#n名#Y异族#n仍在#Z无名小镇#Z作乱，请众位英雄继续加油啊！";
    private static final String PIRATE_COME_NUMOR = "传闻有一批#Y异族#n入侵，现已登陆#Z无名小镇#Z。请能为之士速速前去杀退异族，为民除害！";
    private static final String PIRATE_ALL_KILL_NUMOR = "入侵的异族已全部被消灭！看来中洲大陆真是能人辈出啊！";
    private static final String CONTENT = "异族入侵，尔等凡人，尝尝地府的实力，速速受死！[我要为民除害/" + NpcButton.Fight_the_Alienintrusion.getKey() + "][糟了！遇到异族了，赶紧逃命/逃命]";
    private static final String IN_FIGHT = "异族入侵，尔等凡人，速速受死！[离开]";
    private static final String TEAM_COUNT_NOT_ENOUGH = "区区凡人，也敢来挑衅  至少组队1人再来挑衅我[离开]";
    private static final String TEAM_LEVEL_NOT_ENOUGH = "异族入侵，尔等凡人，也敢来挑衅（队伍中#Y{0}#n的等级不足{1}级，能力不足以除害）[离开]";
    private static final String SPECAIL_REWARD_MESSAGE = "听闻#Y{0}#n在铲除异族时,获得了#Z{1}#Z,请能为之士速速前去杀退异族。";
    private static final String REWARD_MESSAGE = "你获得了一{0}#R{1}#n。";

    /**
     * 特殊奖励，key: 名称，value: 概率
     */
    private static Map<String, Integer> specialRewards = new HashMap<>();
    private static int specialRewardTotalOdd;
    /**
     * 刷新异族，显示在对应的地图上
     */
    public void flushPirate() {
        /**先让之前刷新的海盗消失*/
        hidePirate();

        /**遍历刷新海盗*/
        for (int mapId : MAPIDS) {
            for (int i = 0; i < PIRATE_COUNT_PER_MAP; i++) {
                createPirate(mapId);
            }
        }

        /**发谣言*/
        SpringUtils.getBean(ChatService.class).sendNumor(PIRATE_COME_NUMOR, Const.BRODCAST_MSG_TYPE_ROLE);

        /**增加定时任务，持续时间结束后删除*/
        //SchedulerManager.getInstance().schedule(() -> hidePirate(), PIRATE_CONTINUED_TIME);
    }

    /**
     * 在地图上刷新一个地府叛逆
     */
    private void createPirate(int mapId) {
        Position position = getRandomPosition(mapId);

        NPC npc = new NPC();
        npc.setIcon(PIRATE_ICON);

        npc.setId(SpringUtils.getBean(NewBossService.class).getTempNpcId());
        npc.setX(position.getX());
        npc.setY(position.getY());
        npc.setFangxiang((short) new Random().nextInt(8));/**随机方向*/
        npc.setMapId(mapId);
        npc.setCreateTime(System.currentTimeMillis());
        //npc.setEndTime(npc.getCreateTime() + PIRATE_CONTINUED_TIME);
        npc.setType(NPC.TYPE_ALIEN_INTRUSION);//npc类型
        npc.setContent(CONTENT);
        npc.setName(PIRATE_NAME);
        npc.setBossSetName(PIRATE_NAME);
        bossService.broadcastNpcShow(null, npc);

        DataCache.YIZUXIAOJIANG_NPCS.put(npc.getId(), npc);

        Set<Integer> set = DataCache.PIRATE_MAP_NPC.get(mapId);
        if (set == null) {
            set = new HashSet<>();
            DataCache.PIRATE_MAP_NPC.put(mapId, set);
        }
        DataCache.PIRATE_MAP_NPC.get(mapId).add(npc.getId());
    }

    /**
     * 使所有地府叛逆在对应地图上消失
     */
    public void hidePirate() {

        if (DataCache.YIZUXIAOJIANG_NPCS.size() > 0) {
            List<NPC> list = new ArrayList<>(DataCache.YIZUXIAOJIANG_NPCS.values());
            for (NPC npc : list) {
                if (npc.isInFight()) {
                    /**在战斗中隐藏*/
                    bossService.broadcastNpcHide(null, npc);
                } else {
                    clearPirate(npc);
                }
            }
        }
    }

    /**
     * 移除地府叛逆
     */
    private void clearPirate(NPC npc) {
        if (npc == null) {
            return;
        }

        DataCache.YIZUXIAOJIANG_NPCS.remove(npc.getId());
        Set<Integer> set1 = DataCache.PIRATE_MAP_NPC.get(npc.getMapId());
        if (set1 != null) {
            set1.remove(npc.getId());
        }
        removeUsedPosition(npc.getMapId(), npc.getX(), npc.getY());

        bossService.broadcastNpcHide(null, npc);
    }


    @Override
    protected String getNpcContent(Role role, NPC bossNpc) {
        return null;
    }

    @Override
    public String getNpcContentNotFight(Role role, NPC bossNpc) {
        /**检测是否在战斗中*/
        if (bossNpc.isInFight()) {
            return IN_FIGHT;
        }

        /**检测队伍人数*/
        int teamCount = teamService.getTeamCount(role);
        if (teamCount < MIN_TEAM_COUNT) {
            return TEAM_COUNT_NOT_ENOUGH;
        }

        /**检测等级*/
        Team team = teamService.getTeam(role.getRoleId());
        String names = teamService.checkMember(team, memberRole -> memberRole.getLevel() < ACCEPT_MIN_LEVEL);
        if (names != null) {
            return MessageFormat.format(TEAM_LEVEL_NOT_ENOUGH, names, ACCEPT_MIN_LEVEL);
        }
        names = teamService.checkMember(team, memberRole -> getRoleRemainCount(memberRole) <= 0);
        if (names != null) {
            return "#R" + names + "#n没有挑战次数";
        }
        if (getRoleRemainCount(role) <= 0) {
            return "#R" + role.getName() + "#n没有挑战次数";
        }
        return null;
    }
    private byte getRoleRemainCount(Role role) {
        return (byte) SpringUtils.getActivityService().getRemainCount(role, ActivityType.yizu_ACTIVTY);
    }

    @Override
    public void doStartFight(Role role, NPC bossNpc) {
        List<BossParam> bossParamList = newBossParamList(role, bossNpc);
        BossFightParam bossFightParam = new BossFightParam(bossParamList, getFightType(role));
        bossFightParam.setNpcId(bossNpc.getId());
        Fight fight = bossService.startFightToBoss(role, bossFightParam);
    }

    @Override
    protected int getFightType(Role role) {
        return Const.fightType_Alienintrusion;
    }   //挑战异族

    @Override
    protected NPC getBossNpc(int npcId) {
        return DataCache.YIZUXIAOJIANG_NPCS.get(npcId);
    }

    @Override
    protected void clearNpcAfterWin(Role role, NPC bossNpc) {
        clearPirateAfterFightWin(bossNpc);
    }

    private List<BossParam> newBossParamList(Role role, NPC bossNpc) {
        List<BossParam> bossParamList = new ArrayList<>();
        int count = getBossCount(role);

        /**npc对应的加在第1个*/
        BossSet bossSet = bossService.getBossSet(bossNpc.getBossSetName());
        bossParamList.add(new BossParam(bossSet, bossNpc.getName()));

        /**加count-1个*/
        for (int i = 1; i < count; i++) {
            bossSet = bossService.getBossSet(bossNpc.getBossSetName());
            bossParamList.add(new BossParam(bossSet, bossSet.getName()));
        }
        return bossParamList;
    }

    @Override
    public int getBossCount(Role role) {
        /**最多有10个*/
        int allCount = 10;
        int teamCount = teamService.getTeamCount(role);

        /**根据组队数量计算怪的数量*/
        int count = 0;
        if (teamCount <= 3) {
            int minCount = 6;
            count = ThreadLocalRandom.current().nextInt(allCount - minCount + 1) + minCount;
        } else if (teamCount == 4) {
            int minCount = 8;
            count = ThreadLocalRandom.current().nextInt(allCount - minCount + 1) + (minCount);
        } else {
            count = allCount;
        }
        return count;
    }

    /**
     * 在战斗胜利后移除异族
     */
    private void clearPirateAfterFightWin(NPC npc) {
        int oldPirateCount = DataCache.YIZUXIAOJIANG_NPCS.size();
        /**移除异族操作*/
        clearPirate(npc);
        int newPirateCount = DataCache.YIZUXIAOJIANG_NPCS.size();

        if (newPirateCount != oldPirateCount) {
            if (newPirateCount > 0) {
                /**不是最后一个时，发的谣言*/
                String msg = MessageFormat.format(KILL_MESSAGE, newPirateCount);
                SpringUtils.getChatService().sendNumor(msg, Const.BRODCAST_MSG_TYPE_ROLE);
            } else {
                /**杀死最后一个时，发的谣言*/
                if (oldPirateCount == 1 && newPirateCount == 0) {
                    SpringUtils.getChatService().sendNumor(PIRATE_ALL_KILL_NUMOR, Const.BRODCAST_MSG_TYPE_ROLE);
                }
            }
        }
    }

    /**
     * 给奖励
     */
    public void giveReward(Role role, FightEndEvent fightEndEvent, NPC bossNpc) {
        // 这里改成公共获取配置 经验，道行，武学 奖励。 不再单独写
        SpringUtils.getActivityService().addFinishCount(role, ActivityType.yizu_ACTIVTY, 1);
        fightService.sendBossBasicsReward(role,fightEndEvent);
        fightService.sendBossExtReward(role,fightEndEvent);
    }


    @Override
    protected void clearNpcTimeOut(NPC npc) {
        clearPirate(npc);
    }

    private String getSpecialRewardItem() {
        int index = ThreadLocalRandom.current().nextInt(specialRewardTotalOdd);
        int oddSum = 0;
        for (Map.Entry<String, Integer> entry : specialRewards.entrySet()) {
            oddSum += entry.getValue();
            if (index <= oddSum) {
                return entry.getKey();
            }
        }

        return null;
    }

    @PostConstruct
    private void initSpecialReward() {
        //"X0000033=100", "R0004001=100", "R0002005=10", "R0002006=10", "R0002054=1"
        String[] strings = {"宠风散=100", "超级藏宝图=100", "超级灵石=10", "超级晶石=10"};
        Map<String, Integer> rewards = new HashMap<>();
        int totalOdd = 0;
        for (String ss : strings) {
            String[] sss = ss.split("=");
            String key = sss[0];
            int odd = Integer.parseInt(sss[1]);
            rewards.put(key, odd);
            totalOdd = totalOdd + odd;
        }
        specialRewards = rewards;
        specialRewardTotalOdd = totalOdd;
    }

}
